let reactiveFn = null

/**
 * Depend类收集依赖
 */
class Depend {
  constructor() {
    this.reactiveFns = new Set()
  }

  depend() {
    if (reactiveFn) {
      this.reactiveFns.add(reactiveFn)
    }
  }

  notify() {
    this.reactiveFns.forEach(fn => {
      fn()
    })
  }
}

/**
 * 获取depend依赖
 */
let reactiveMap = new WeakMap()
const getDepend = (obj, key) => {
  let objMap = reactiveMap.get(obj)
  if (!objMap) {
    objMap = new Map()
    reactiveMap.set(obj, objMap)
  }
  let dep = objMap.get(key)
  if (!dep) {
    dep = new Depend()
    objMap.set(key, dep)
  }
  return dep
}

/**
 * 检测需要依赖变化执行的fn
 */
const watch = function (fn) {
  reactiveFn = fn
  fn()
  reactiveFn = null
}

/**
 * 响应式函数代理对象obj
 */
const reactive = (target) => {
  return new Proxy(target, {
    get(target, key, receiver) {
      const dep = getDepend(target, key)
      dep.depend()
      return Reflect.get(target, key, receiver)
    },
    set(target, key, value, receiver) {
      Reflect.set(target, key, value, receiver)
      const dep = getDepend(target, key)
      dep.notify()
    }
  })
}

/*************************测试**********************/
const obj = reactive({
  address: '北京'
})

watch(() => {
  console.log('我依赖了obj.addess，我需要被调用', obj.address)
})

obj.address = '广州'
